package org.joshsacks.fishies.ui.gl;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import org.joshsacks.fishies.FishiesController;
import org.joshsacks.fishies.GameBoard;
import org.joshsacks.fishies.GameBoard.GamePieceType;
import org.joshsacks.fishies.GameBoard.SlideDownSet;

public class GameBoardRenderer {
  private static final int INSET = 2;
  private static final int TILE_SIZES[] = {32, 48, 64, 80, 96};
  private static int tileSizeIndex;
  private final GameBoard gameBoard;
  private final TextureManager textureManager;
  private final List<List<Integer>> listOfTypes;
  
  private SlideDownSet slideDownSet;
  private long slideDownAnimaionStart;
  
  public static void calculateSizeIndex(int width, int height) {
    System.err.println("Width: " + width + " H: " + height);
    width -= 4;
    int widthIndex = TILE_SIZES.length - 1;
    for (; widthIndex > 0 && 
        width / TILE_SIZES[widthIndex] < GameBoard.WIDTH; widthIndex--);

    // +3 tiles for scores and touch icons.
    final int vTiles = GameBoard.HEIGHT + 3; 
    int heightIndex = TILE_SIZES.length - 1;
    for (; heightIndex > 0 && 
        height / TILE_SIZES[heightIndex] < vTiles; heightIndex--) {
    }
    
    System.err.println("W: " + widthIndex + " H: " + heightIndex);
    tileSizeIndex = Math.min(heightIndex, widthIndex);
  }
  
  public static int getTileSizeIndex() {
    return tileSizeIndex;
  }
  
  public static int getTileSize() {
    return TILE_SIZES[tileSizeIndex];
  }
  
  public static int getXOffset() {
    return INSET;
  }
  
  public static int getYOffset() {
    return INSET * 2;
  } 
  
  public GameBoardRenderer(GameBoard gameBoard, TextureManager textureManager) {
    this.gameBoard = gameBoard;
    this.textureManager = textureManager;
    listOfTypes = new ArrayList<List<Integer>>(GamePieceType.values().length);
    for (GamePieceType gamePiece : GamePieceType.values()) {
      listOfTypes.add(new ArrayList<Integer>());
    }
  }
  
  public void render(GL10 gl) {
    SquareRenderer outline = new SquareRenderer(gl);
    gl.glDisable(GL10.GL_TEXTURE_2D);
    outline.addRectangle(-INSET, -INSET, INSET, getTileSize() * 14, null);    
    outline.addRectangle(
            -INSET, -INSET, getTileSize() * GameBoard.WIDTH + INSET * 2, INSET, null);
    outline.addRectangle(
            getTileSize() * GameBoard.WIDTH, -INSET, INSET, getTileSize() * 14, null);
    gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    outline.draw();
    gl.glEnable(GL10.GL_TEXTURE_2D);
    
    for (GamePieceType gamePiece : GamePieceType.values()) {
      listOfTypes.get(gamePiece.ordinal()).clear();
    }
    
    for(int w = 0; w < GameBoard.WIDTH; w++) {
      for (int h = 0; h < GameBoard.HEIGHT; h++) {
        GamePieceType value = gameBoard.getPosition(w, h);
        if (value != null) {
          listOfTypes.get(value.ordinal()).add(w * GameBoard.HEIGHT + h);       
        }
      }
    }
    
    for (GamePieceType type : GamePieceType.values()) {
      List<Integer> positions = listOfTypes.get(type.ordinal());
      if (positions.size() > 0) {
        SquareRenderer renderer = new SquareRenderer(gl);
        for (Integer integer : positions) {
          int w = integer / GameBoard.HEIGHT;
          int h = integer % GameBoard.HEIGHT;
          float slide = 0;
          if (slideDownSet != null && slideDownSet.shouldSlide(w, h)) {
            slide = (System.currentTimeMillis() - slideDownAnimaionStart) / 
                (float) FishiesController.SLIDE_DURATION * getTileSize();
          }
          renderer.addSquare(w * getTileSize(), 
                  h * getTileSize() - slide, getTileSize(), false);       
        }
        textureManager.setTexture(gl, type.ordinal());
        renderer.draw();
      }
    }   
  }

  public void setSlideDownSet(SlideDownSet slideDownSet) {
    this.slideDownSet = slideDownSet;
    if (slideDownSet != null) {
      slideDownAnimaionStart = System.currentTimeMillis();
    }
  }
}
